package com.service.business.pay.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.beust.jcommander.internal.Lists;
import com.service.business.base.dto.LoginUserSession;
import com.service.business.base.service.ConfigService;
import com.service.business.framework.log.RequestLog;
import com.service.business.member.dto.MemberStoreChange;
import com.service.business.member.service.MemberCacheService;
import com.service.business.member.service.MemberGradeConfigService;
import com.service.business.member.service.MemberService;
import com.service.business.member.service.MemberStoreService;
import com.service.business.order.service.*;
import com.service.dao.dto.MemberGradeCheckDto;
import com.service.business.pay.controller.rep.PayTypeRep;
import com.service.business.pay.controller.req.PayOrderReq;
import com.service.business.pay.controller.req.PayProductOtherOrderReq;
import com.service.business.pay.service.PayService;
import com.service.business.product.service.ProductPayTypeService;
import com.service.business.support.MemberStoreLockUtils;
import com.service.business.support.OrderLockUtils;
import com.service.business.support.SessionUtil;
import com.service.business.support.VerifyCodeUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.BaseController;
import com.service.core.rest.response.BaseResponse;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.enums.*;
import com.service.dao.model.*;
import com.service.dao.po.MemberCache;
import lombok.extern.slf4j.Slf4j;
import org.redisson.RedissonRedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <dl>
 * <dt>back-end</dt>
 * <dd>Description:</dd>
 * <dd>Copyright: Copyright (C) 2015</dd>
 * <dd>Company: </dd>
 * <dd>CreateDate: 2019年11月15日</dd>
 * </dl>
 *
 * @author
 */
@RestController
@RequestMapping("pay")
@Slf4j
public class PayController extends BaseController {

	@Autowired
	private PayService payService;
	@Autowired
	private SessionUtil sessionUtil;
	@Autowired
	private MemberService memberService;
	@Autowired
	private ConfigService configService;
	@Autowired
	private OrderLockUtils orderLockUtils;
	@Autowired
	private MemberStoreLockUtils memberStoreLockUtils;
	@Autowired
	private MemberStoreService memberStoreService;
	@Autowired
	private ProductPayTypeService productPayTypeService;
	@Autowired
	private OrderProductOtherService orderProductOtherService;
	@Autowired
	private VerifyCodeUtil verifyCodeUtil;
	@Autowired
	private OrderProductHrComboService orderProductHrComboService;
	@Autowired
	private OrderProductHrComboDetailsService orderProductHrComboDetailsService;
	@Autowired
	private OrderProductOtherTotalService orderProductOtherTotalService;
	@Autowired
	private OrderProductLockComboService orderProductLockComboService;
	@Autowired
	private MemberGradeConfigService gradeConfigService;
	@Autowired
	private MemberCacheService memberCacheService;

	@RequestLog("其他产品支付")
	@PostMapping("product-other/{orderNo}")
	public BaseResponse payProductOther(@PathVariable("orderNo") String orderNo, @RequestBody @Validated PayProductOtherOrderReq payOrderReq) {
		LoginUserSession session = sessionUtil.getUser();
		if(session.getStoreFreezeStatus() == com.service.dao.enums.MemberEnums.StoreStatus.FROZEN.getCode()){
			throw new CommonException("账户资产已冻结，如有疑问请联系客服","account_assets_frozen");
		}
		memberService.validSafetyPwd(session.getUserId(), payOrderReq.getSafetyPwd());

		List<String> lockKey = Lists.newArrayList(orderLockUtils.buildOtherOrderLockKey(orderNo));
		OrderProductOther orderProductOther = orderProductOtherService.getOrderByOrderNo4Pay(orderNo);

		List<OrderProductOtherTotal> totalList = orderProductOtherTotalService.listTotalByOrderId(orderProductOther.getId());
		Map<String, BigDecimal> totalMap = orderProductOtherTotalService.listTotalByOrderId2Map(totalList);

		List<MemberStore> storeList = Lists.newArrayList();
		totalMap.keySet().forEach(item -> storeList.add(memberStoreService.getMemberStore(session.getUserId(), item)));
		lockKey.addAll(MemberStoreLockUtils.buildStoreKey2List(storeList));

		RedissonRedLock redLock = orderLockUtils.getRedLock(lockKey);
		if (orderLockUtils.redLockTryLock(redLock)) {
			try {
				Map<String, SysConfig> configMap = configService.getConfigMapByGroup(ConfigConstants.Group.mall.getCode());
				payService.payProductOtherOrder(orderNo, orderProductOther, totalMap, totalList, configMap);
			} finally {
				redLock.unlock();
			}
		}
		return successBaseResponse();
	}

	@RequestLog("算力套餐支付")
	@PostMapping("product-hr-combo/{orderNo}")
	public BaseResponse payProductHrCombo(@PathVariable("orderNo") String orderNo, @RequestBody @Validated PayOrderReq payOrderReq) {
		LoginUserSession session = sessionUtil.getUser();
		if(session.getStoreFreezeStatus().equals(MemberEnums.StoreStatus.FROZEN.getCode())){
			throw new CommonException("账户资产已冻结，如有疑问请联系客服","account_assets_frozen");
		}
//		verifyCodeUtil.verifyTextVerifyCode(session.getAccount(), payOrderReq.getVerifyCode(), SmsTypeEnum.PAY);

		payService.pay(payOrderReq,session,orderNo);
//		//用户上级团队新增算力业绩
		OrderProductHrCombo orderProductHrCombo = orderProductHrComboService.getOrderDetailByOrderNo(orderNo);
		OrderProductHrComboDetails orderProductHrComboDetails = orderProductHrComboDetailsService.getOne(new QueryWrapper<OrderProductHrComboDetails>().lambda()
				.eq(OrderProductHrComboDetails::getHrOrderId, orderProductHrCombo.getId())
		);
		checkGradeByOrder(orderProductHrCombo,orderProductHrComboDetails);


//		orderHrComboSendHandler.sendPayHrComboMsg(HrComboOrder.builder()
//				.orderId(orderProductHrCombo.getId())
//				.memberId(orderProductHrCombo.getMemberId())
//				.build());
		return successBaseResponse();
	}

//	@RequestLog("存币(锁仓)套餐支付")
//	@PostMapping("product-lock-combo/{lockNo}")
//	public BaseResponse payProductLockCombo(@PathVariable("lockNo") String lockNo, @RequestBody @Validated PayOrderReq payOrderReq) {
//		LoginUserSession session = sessionUtil.getUser();
//		verifyCodeUtil.verifyTextVerifyCode(session.getAccount(), payOrderReq.getVerifyCode(), SmsTypeEnum.PAY);
//		memberService.validSafetyPwd(session.getUserId(), payOrderReq.getSafetyPwd());
//		OrderProductLockCombo orderProductLockCombo = orderProductLockComboService.getOne(new QueryWrapper<OrderProductLockCombo>().lambda()
//				.eq(OrderProductLockCombo::getLockNo, lockNo)
//				.eq(OrderProductLockCombo::getOrderStatus, HashRateOrderEnums.Status.not_pay.getCode())
//		);
//		List<String> lockKey = Lists.newArrayList(orderLockUtils.buildLockOrderLockKey(lockNo));
//		List<PayTypeRep> payTypeRepList = buildMemberStoreKeyAndPayTypeList(orderProductLockCombo.getOrderType(), payOrderReq.getPayGroup(), session, lockKey);
//		RedissonRedLock redLock = orderLockUtils.getRedLock(lockKey);
//		if (orderLockUtils.redLockTryLock(redLock)) {
//			try {
//				payService.payProductLockComboOrder(lockNo, orderProductLockCombo, payTypeRepList, payOrderReq);
//			} finally {
//				redLock.unlock();
//			}
//		}
//		return successBaseResponse();
//	}

	private List<PayTypeRep> buildMemberStoreKeyAndPayTypeList(Integer orderType, Integer payGroup, LoginUserSession session, List<String> lockKey) {
		List<PayTypeRep> payTypeRepList = productPayTypeService.listByOrderTypeAndPayGroup(orderType, payGroup);
		for (PayTypeRep payTypeRep : payTypeRepList) {
			MemberStore memberStore = memberStoreService.getMemberStore(session.getUserId(), payTypeRep.getCoinsName());
			lockKey.add(MemberStoreLockUtils.buildStoreKey(memberStore.getMemberId(), memberStore.getId()));
		}
		return payTypeRepList;
	}

	/**
	 * 支付成功后续处理用户等级升级问题
	 *
	 * @param orderProductHrCombo
	 * @param comboDetails
	 */
	public void checkGradeByOrder(OrderProductHrCombo orderProductHrCombo, OrderProductHrComboDetails comboDetails) {
		//根据购买用户推荐关系查询用户列表
		Member member = memberService.getMemberById(orderProductHrCombo.getMemberId());
		//用户推荐关系网络倒叙获取
		List<Integer> teamIds = splitByUserPathDESC(member);
		if(!ObjectUtils.isEmpty(teamIds)){
			for(Integer memberId:teamIds){
				Member teamMember = memberService.getMemberById(memberId);
				MemberGradeConfig config = new MemberGradeConfig();
				Integer umbrellaGradeOneNum = 0;
				Integer umbrellaGradeTwoNum = 0;
				Integer umbrellaGradeThreeNum = 0;
				Integer umbrellaGradeFourNum = 0;
				BigDecimal umbrellaHashRates = BigDecimal.ZERO;
				if(!ObjectUtils.isEmpty(teamMember)){
					List<Member> memberList = memberService.selectByPathAndStatus(memberId);
					if(!ObjectUtils.isEmpty(memberList)){
						List<Integer> memberIdList = memberList.stream().map(Member::getId).collect(Collectors.toList());
						umbrellaHashRates = orderProductHrComboService.totalUmbrellaEffectiveHashRateByMemberIdsAndStatus(memberIdList, HashRateOrderEnums.getHrComboTotalStatus());
						for(Member umbrella: memberList){
							if(umbrella.getVipGrade() == GradeEnum.two.getValue() || umbrella.getVipGrade() == GradeEnum.twelve.getValue()){
								umbrellaGradeOneNum = umbrellaGradeOneNum + 1;
							}else if(umbrella.getVipGrade() == GradeEnum.three.getValue() || umbrella.getVipGrade() == GradeEnum.thirteen.getValue()){
								umbrellaGradeTwoNum = umbrellaGradeTwoNum + 1;
							}else if(umbrella.getVipGrade() == GradeEnum.four.getValue() || umbrella.getVipGrade() == GradeEnum.fourteen.getValue()){
								umbrellaGradeThreeNum = umbrellaGradeThreeNum + 1;
							}else if(umbrella.getVipGrade() == GradeEnum.five.getValue() || umbrella.getVipGrade() == GradeEnum.fifteen.getValue()){
								umbrellaGradeFourNum = umbrellaGradeFourNum + 1;
							}
						}
					}else{
						List<Integer> memberIdList = new ArrayList<>();
						memberIdList.add(teamMember.getId());
						umbrellaHashRates = orderProductHrComboService.totalUmbrellaEffectiveHashRateByMemberIdsAndStatus(memberIdList, HashRateOrderEnums.getHrComboTotalStatus());
					}
					config.setUmbrellaHashRateNumLimit(umbrellaHashRates);
					config.setVipGradeOneNumLimit(umbrellaGradeOneNum);
					config.setVipGradeTwoNumLimit(umbrellaGradeTwoNum);
					config.setVipGradeThreeNumLimit(umbrellaGradeThreeNum);
					config.setVipGradeFourNumLimit(umbrellaGradeFourNum);
					//循环判断用户的等级是否满足条件，并修改用户等级
					MemberGradeConfig memberGradeConfig = gradeConfigService.getByCheckGradeDto(config);
					if(!ObjectUtils.isEmpty(memberGradeConfig)){
						if(teamMember.getVipGrade() < memberGradeConfig.getId()){
							MemberCache memberCache = memberCacheService.getMemberCache(memberId);
							if(!ObjectUtils.isEmpty(memberCache)){
								memberCache.setMemberGrade(memberGradeConfig.getId());
								memberCache.setMemberGradeName(memberGradeConfig.getGradeName());
								memberCacheService.setMemberCache(memberCache);
							}
							//同步修改用户等级
							memberService.updateMemberGrade(memberId, memberGradeConfig.getId());
						}
					}
				}
			}
		}
	}


	/**
	 * @Description: 根据用户路径获取用户除去自身的所有上级用户列表
	 * @Author: ty
	 * @Date: 2021/6/23 17:20
	 * @param: [buyMember]
	 * @return: java.util.List<com.service.dao.po.MemberCache>
	 **/
	public List<Integer> splitByUserPathDESC(Member buyMember){
		if(ObjectUtils.isEmpty(buyMember)){
			return null;
		}
		String userPath = buyMember.getUserPath();
		if(ObjectUtils.isEmpty(userPath)){
			userPath = "-" +buyMember.getId() + "-";
		}else{
			userPath = userPath + buyMember.getId() + "-";
		}

		String[] idStrs = userPath.split("-");
		List<Integer> memberIds = new ArrayList<>();
		for(String idStr : idStrs){
			if(ObjectUtils.isEmpty(idStr)){
				continue;
			}
			memberIds.add(Integer.parseInt(idStr));
		}
		if(ObjectUtils.isEmpty(memberIds)){
			return null;
		}
		Collections.sort(memberIds,new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				// 返回值为int类型，大于0表示正序，小于0表示逆序
				return o2-o1;
			}
		});
		return memberIds;
	}
}
